Skip to content

feat(agent): gather thread_ts or message ts of events outside of assistant context#1444

Open
zimeg wants to merge 5 commits intozimeg-feat-agent-set-suggested-promptsfrom
zimeg-feat-context-ts
Open

feat(agent): gather thread_ts or message ts of events outside of assistant context#1444
zimeg wants to merge 5 commits intozimeg-feat-agent-set-suggested-promptsfrom
zimeg-feat-context-ts

Conversation

@zimeg
Copy link
Member

@zimeg zimeg commented Feb 16, 2026

Summary

This PR gathers the thread_ts or message ts of events and saves these as the internal thread for the agent argument 👾

Fixes an issue where streamed responses and set status errors in a public channel.

Testing

slack-samples/bolt-python-assistant-template#51

from slack_bolt import BoltAgent, Say


def app_mentioned_callback(
    agent: BoltAgent,
    say: Say,
):
    """
    Handles the event when the app is mentioned in a Slack conversation
    and generates an AI response.
    Args:
        agent: BoltAgent for making API calls
        say: Function to send messages to the thread from the app
    """
    try:
        agent.set_status(
            status="thinking...",
            loading_messages=[
                "Teaching the hamsters to type faster…",
                "Untangling the internet cables…",
                "Consulting the office goldfish…",
                "Polishing up the response just for you…",
                "Convincing the AI to stop overthinking…",
            ],
        )
        say("LGTM!")

Category

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run ./scripts/install_all_and_run_tests.sh after making the changes.

@zimeg zimeg self-assigned this Feb 16, 2026
@zimeg zimeg requested a review from a team as a code owner February 16, 2026 21:54
@zimeg zimeg added enhancement New feature or request semver:patch experiment Experimental feature documented with ExperimentalWarning and pydoc Experiment section labels Feb 16, 2026
@zimeg zimeg changed the title feat(agent): gather thread_ts or message ts of events outside of assistant feat(agent): gather thread_ts or message ts of events outside of assistant context Feb 16, 2026
@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.67%. Comparing base (956f5f5) to head (2c664c1).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                           Coverage Diff                           @@
##           zimeg-feat-agent-set-suggested-prompts    #1444   +/-   ##
=======================================================================
  Coverage                                   90.66%   90.67%           
=======================================================================
  Files                                         226      226           
  Lines                                        7202     7205    +3     
=======================================================================
+ Hits                                         6530     6533    +3     
  Misses                                        672      672           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member Author

@zimeg zimeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗣️ A few comments of thoughts for reviewers so kind!


# Resolve thread_ts: assistant events set context.thread_ts, otherwise read from event
event = request.body.get("event", {})
thread_ts = request.context.thread_ts or event.get("thread_ts") or event.get("ts")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 note: We avoided adding a new ts value to the listener context in this PR and instead use the event information. This was to keep scope changes minimal and parity with the Bolt JS implementation IIRC.

@@ -218,6 +218,9 @@ def extract_thread_ts(payload: Dict[str, Any]) -> Optional[str]:
# This utility initially supports only the use cases for AI assistants, but it may be fine to add more patterns.
# That said, note that thread_ts is always required for assistant threads, but it's not for channels.
# Thus, blindly setting this thread_ts to say utility can break existing apps' behaviors.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️‍🗨️ thought: I'm surprised that say posts top-level messages in response to threaded messages by default TBH!

I agree that a "fix" for this, to respond in thread if a thread_ts is present, might cause new behavior for apps but am wondering if this is intended behavior or something to ponder changing in the future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm good question! id love to hear what changing it in the future would look like 🤔 to me it makes sense for apps to respond in thread

Comment on lines +92 to +95
# Resolve thread_ts: assistant events set context.thread_ts, otherwise read from event
event = request.body.get("event", {})
thread_ts = request.context.thread_ts or event.get("thread_ts") or event.get("ts")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice ⭐ thanks for fixing this!

Copy link
Member

@mwbrooks mwbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: @zimeg Thanks a bunch for this PR! I'll look over it today.

I noticed that thread_ts is set to either thread_ts or ts. Is this the behaviour we want throughout all of Bolt? While chat_stream requires a thread_ts argument that must be ts when thread_ts isn't present... I don't think that's consistent with other methods. My concern is that setting thread_ts to a non-thread message could have unexpected side effects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request experiment Experimental feature documented with ExperimentalWarning and pydoc Experiment section semver:patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants